package com.carkeeper.tweet.service.impl;

import com.carkeeper.tweet.dao.ESManagerMapper;
import com.carkeeper.tweet.dao.TweetMapper;
import com.carkeeper.tweet.pojo.Tweet;
import com.carkeeper.tweet.service.TweetService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @program: carkeeper_parent
 * @Date: 2020/11/23 14:22
 * @Author: qgg
 * @Description:
 */
@Service
public class TweetServiceImpl implements TweetService {

    @Autowired
    private TweetMapper tweetMapper;

    @Autowired
    private ESManagerMapper esManagerMapper;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    //创建索引结构
    @Override
    public void createIndexAndMapping() {
        //创建索引
        elasticsearchTemplate.createIndex(Tweet.class);

        //创建映射
        elasticsearchTemplate.putMapping(Tweet.class);
    }

    @Override
    public void delDataById(String message) {

    }

    @Override
    public void importDataToESById(String message) {

    }

    @Override
    public void importAll() {
        List<Tweet> tweetList = tweetMapper.selectAll();

        if (tweetList == null || tweetList.size() < 0){
            throw new RuntimeException("当前没有数据被查询到，无法导入数据库");
        }

        //批量存入索引库
        esManagerMapper.saveAll(tweetList);
    }


    //查询所有
    @Override
    public List<Tweet> findAll() {

        List<Tweet> tweetList = tweetMapper.selectAll();
        return tweetList;
    }

    //添加
    @Override
    public void add(Tweet tweet) {
        tweetMapper.insert(tweet);
        esManagerMapper.save(tweet);
    }

    //删除
    @Override
    public void delete(String id) {
        System.out.println("id = " + id);

        if (StringUtils.isEmpty(id)){
            throw new RuntimeException("数据为空!");
        }
        //删除数据库中的数据
        tweetMapper.deleteByPrimaryKey(id);

        //删除es中的数据
        esManagerMapper.deleteById((long) Integer.parseInt(id));
    }

    //修改
    @Override
    public void update(Tweet tweet){
        tweetMapper.updateByPrimaryKey(tweet);
    }

    //根据id查询数据
    @Override
    public Tweet findById(String id){
        Tweet tweet = tweetMapper.selectByPrimaryKey(id);
        return tweet;
    }



    //多条件查询
    @Override
    public List<Tweet> findList(Map<String, Object> searchMap , String currentPage, String pageSize) {

        System.out.println("searchMap = " + searchMap);

        HashMap<String, Object> resultMap = new HashMap<>();

        //第一步  非空判断
        if (searchMap != null){

            NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();

            //组合条件查询
            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

            System.out.println("boolQuery = " + boolQuery);

            if (!StringUtils.isEmpty(searchMap.get("name"))){
                boolQuery.must(QueryBuilders.matchQuery("name" , searchMap.get("name")).operator(Operator.AND));
            }


            //判断分类是否有查询条件
            if (!StringUtils.isEmpty(searchMap.get("type"))){
                boolQuery.filter(QueryBuilders.termQuery("type", searchMap.get("type")));
            }


            //判断一级分类是否有查询条件
            if (!StringUtils.isEmpty(searchMap.get("type01Name"))){
                boolQuery.filter(QueryBuilders.termQuery("type01Name", searchMap.get("type01Name")));
            }


            //判断二级分类是否有查询条件
            if (!StringUtils.isEmpty(searchMap.get("type02Name"))){
                boolQuery.filter(QueryBuilders.termQuery("type02Name", searchMap.get("type02Name")));
            }


            //分页查询
            currentPage = currentPage == null || "".equals(currentPage.trim()) ? "1" : currentPage;
            pageSize = pageSize == null || "".equals(pageSize.trim()) ? "10" : pageSize;
            try {
                nativeSearchQueryBuilder.withPageable(PageRequest.of(Integer.parseInt(currentPage)-1,Integer.parseInt(pageSize)));
            } catch (NumberFormatException e) {
                e.printStackTrace();
                throw new RuntimeException("请输入正确的分页信息！");
            }

            //4 原生搜索实现类
            nativeSearchQueryBuilder.withQuery(boolQuery);

            //执行查询
            AggregatedPage<Tweet> page = elasticsearchTemplate.queryForPage(nativeSearchQueryBuilder.build(), Tweet.class);

            System.out.println("page = " + page);

            //获取查询结果
            List<Tweet> content = page.getContent();

            System.out.println("content = " + content);

            return content;

        }

        return null;
    }


    /**
     * 查询全部分类
     *
     * @param map
     * @return
     */
    @Override
    public Map<String, Object> searchCategory(Map<String, String> map) {

        //创建添加条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //执行条件
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder);


        String id = map.get("id");
        if (!StringUtils.isEmpty(id)) {
            //根据id查询
            boolQueryBuilder.must(QueryBuilders.termQuery("id", id));
        }

        //判断总分类是否有查询条件
        String type = map.get("type");
        if (!StringUtils.isEmpty(type)) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("type", type));
        }

        //判断一级分类是否有查询条件
        String type01Name = map.get("type01Name");
        if (!StringUtils.isEmpty(type01Name)) {
            boolQueryBuilder.filter(QueryBuilders.termQuery(type01Name, "type01Name"));
        }

        //判断二级分类是否有查询条件
        String type02Name = map.get("type02Name");
        if (!StringUtils.isEmpty(type02Name)) {
            boolQueryBuilder.filter(QueryBuilders.termQuery(type02Name, "type02Name"));
        }

        type = "type";
        //添加聚合函数
        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms(type).field("type"));

        String type01 = "type01Name";
        //添加聚合函数
        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms(type01).field("type01Name"));

        String type02 = "type02Name";
        //添加聚合函数
        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms(type02).field("type02Name"));


        //开始查询
        AggregatedPage<Tweet> page = elasticsearchTemplate.queryForPage(nativeSearchQueryBuilder.build(), Tweet.class);
        //获取聚合完毕内容
        Aggregation aggregation = (StringTerms) page.getAggregation(type);
        Aggregation aggregation01 = (StringTerms) page.getAggregation(type01);
        Aggregation aggregation02 = (StringTerms) page.getAggregation(type02);
        //创建集合
        List aggregationList = new ArrayList<String>();
        List aggregation01List = new ArrayList<String>();
        List aggregation02List = new ArrayList<String>();
        List<StringTerms.Bucket> buckets = ((StringTerms) aggregation01).getBuckets();
        //遍历
        for (StringTerms.Bucket bucket : buckets) {
            aggregation01List.add(bucket.getKeyAsString());
        }
        List<StringTerms.Bucket> buckets1 = ((StringTerms) aggregation02).getBuckets();
        //遍历
        for (StringTerms.Bucket bucket : buckets1) {
            aggregation02List.add(bucket.getKeyAsString());
        }
        List<StringTerms.Bucket> buckets2 = ((StringTerms) aggregation).getBuckets();
        //遍历
        for (StringTerms.Bucket bucket : buckets2) {
            aggregationList.add(bucket.getKeyAsString());
        }
        //创建map集合封装返值
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("type", aggregationList);
        resultMap.put("type01Name", aggregation01List);
        resultMap.put("type02Name", aggregation02List);

        return resultMap;
    }

}
